#ifndef BASE_CONN_H
#define BASE_CONN_H

#include <boost/asio.hpp>
namespace asio = boost::asio;

#include <boost/shared_ptr.hpp>

#include "network/asio_dgram_conn.h"

#include "util/ScopeExitSignal.h"

typedef dgram::conn<asio::ip::udp> UdpSock;
typedef dgram::conn_service<asio::ip::udp> UdpService;

typedef boost::shared_ptr<class BaseConn> BaseConnRef;
class BaseConn {
	private:
		static void refClear(BaseConnRef ref);
		void dispose(BaseConnRef ref);

	protected:
		asio::io_service& service;
		asio::ip::tcp::socket tcpconn;
		UdpSock udpconn;

		typedef boost::shared_ptr<ScopeExitSignal> Token;
		Token token;

		uint8 sendbuf[1400];
		uint8 recvbuf[1400];

		uint8 tcpbuf[1400];
		uint8 udpbuf[1400];

		void startForwarding();
		void handleSendToUdp   (Token tk, const boost::system::error_code& e);
		void handleRecvFromUdp (Token tk, const boost::system::error_code& e, size_t len);
		void handleSendToTcp   (Token tk, const boost::system::error_code& e);
		void handleRecvFromTcp (Token tk, const boost::system::error_code& e, size_t len);

	public:
		BaseConn(asio::io_service& ioservice_, UdpService& udpservice);

		void giveSelfRef(BaseConnRef ref);
		void close();

		asio::ip::tcp::socket& getTcpConn();
		UdpSock& getUdpConn();

		virtual ~BaseConn();
};

#endif//BASE_CONN_H
